package main.userInterface.hexislandui;


import main.model.hexisland.HexIsland;
import main.model.hexisland.tile.TileFactory;
import main.model.hexisland.tile.TileTree;
import main.model.hexisland.tile.TileType;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.*;


@SuppressWarnings("serial")
public class HexEditorPanel extends JPanel{
    private HexIslandCanvas islandCanvas;
    private HexIsland island;
    //private IOController io;

    JButton randomButton = new JButton("Randomise Island");
    JButton clearButton = new JButton("Clear Island");

    JSlider xSlider, ySlider;
    JLabel xLab, yLab;
    JButton applySizeButton = new JButton("Apply Size");

    ButtonGroup group;
    JRadioButton sandButton, rockButton, waterButton, grassButton, treeButton;


    int health = TileTree.getTreeMax();
    double sampleSize = 20.0;
    HexTileSampler sandSampler = new HexTileSampler(TileType.SAND, sampleSize , 1);
    HexTileSampler rockSampler = new HexTileSampler(TileType.ROCK, sampleSize , 1);
    HexTileSampler waterSampler = new HexTileSampler(TileType.WATER, sampleSize , 1);
    HexTileSampler grassSampler = new HexTileSampler(TileType.GRASS, sampleSize , 1);
    HexTileSampler treeSampler = new HexTileSampler(TileType.TREE, sampleSize , health);
    HexTileSampler largeTreeSampler = new HexTileSampler(sampleSize , health);

    JSlider healthSlider;
    JLabel healthLab;

    int ISLAND_MIN = 10;
    int ISLAND_MAX = 50;
    int ISLAND_INIT = 10;

    //boolean CLICK = false;
    private TileType selectedTileType = TileType.SAND;


    public HexEditorPanel(HexIsland hexIsland, HexIslandCanvas canvas){
        this.setLayout(new BorderLayout());
        
        //io = new AbstractIOController();
        this.island = hexIsland;
        islandCanvas = canvas;

        ISLAND_MIN = island.getMinSize();
        ISLAND_MAX = island.getMaxSize();
        ISLAND_INIT = island.getDefaultSize();
        
        //SAVEPAN settings
        //JPanel loadsavePan = new JPanel();
        //loadsavePan.setLayout(new BoxLayout(loadsavePan,BoxLayout.PAGE_AXIS));
        
        //JPanel loadPan = new JPanel(new BorderLayout());
        //JPanel loadLabPan = new JPanel(new GridLayout(0,1,0,0));
        //loadLabPan.add(dirIntroLab);
        //dirLab = new JLabel(RIO.getFileString(loadedDirectory));
        //loadLabPan.add(dirLab);
        //loadLabPan.add(explainLab);
        //loadLabPan.setAlignmentX(Component.RIGHT_ALIGNMENT);
        
        //JPanel loadChoicesPan = new JPanel();
        //loadChoicesPan.setLayout(new BoxLayout(loadChoicesPan,BoxLayout.PAGE_AXIS));
        //choicesArea = new JList();
        //choicesArea.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        //choicesArea.setLayoutOrientation(JList.VERTICAL);
        //JScrollPane choicesScroll = new JScrollPane(choicesArea);
        //choicesScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        //choicesScroll.setAlignmentX(Component.CENTER_ALIGNMENT);
        //chooseDir.setAlignmentX(Component.RIGHT_ALIGNMENT);
        //loadChoicesPan.add(choicesScroll);
        //loadChoicesPan.add(chooseDir);
        
        //loadPan.add(loadLabPan, BorderLayout.PAGE_START);
        //loadPan.add(loadChoicesPan, BorderLayout.CENTER);
        //loadPan.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        //BorderFactory.createTitledBorder("Loading Options"), BorderFactory.createEmptyBorder(5,5,5,5)), loadPan.getBorder()));
        
        //JPanel savePan = new JPanel(new GridLayout(0,1));
        //savePan.add(saveBut);
        ///savePan.add(saveAsBut);
        //savePan.add(loadBut);
        ///savePan.add(deleteBut);
        //savePan.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        //BorderFactory.createTitledBorder("Saving Options"), BorderFactory.createEmptyBorder(5,5,5,5)), savePan.getBorder()));
        
        //loadsavePan.add(loadPan);
        //loadsavePan.add(savePan);
        
        //PANELS FOR SIZE
        JPanel islandsize = new JPanel();
        islandsize.setLayout(new BoxLayout(islandsize,BoxLayout.PAGE_AXIS));
        
        JPanel islandsizeX = new JPanel();
        xSlider = new JSlider(JSlider.HORIZONTAL,ISLAND_MIN,ISLAND_MAX,ISLAND_INIT);
        xSlider.setMajorTickSpacing(10);
        xSlider.setMinorTickSpacing(5);
        //xSlider.setPaintTicks(true);
        //xSlider.setPaintLabels(true);
        xLab = new JLabel("X: "+xSlider.getValue());
        islandsizeX.add(xSlider);
        islandsizeX.add(xLab);
        
        JPanel islandsizeY = new JPanel();
        ySlider = new JSlider(JSlider.HORIZONTAL,ISLAND_MIN,ISLAND_MAX,ISLAND_INIT);
        ySlider.setMajorTickSpacing(10);
        ySlider.setMinorTickSpacing(5);
        //ySlider.setPaintTicks(true);
        //ySlider.setPaintLabels(true);
        yLab = new JLabel("Y: "+ySlider.getValue());
        islandsizeY.add(ySlider);
        islandsizeY.add(yLab);
        
        islandsize.add(islandsizeX);
        islandsize.add(islandsizeY);
        islandsize.add(applySizeButton);
        islandsize.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Set Island Size"), BorderFactory.createEmptyBorder(5,5,5,5)), islandsize.getBorder()));

        //TERchoose SETTINGS
        JPanel TERchoose = new JPanel();
        TERchoose.setLayout(new BoxLayout(TERchoose,BoxLayout.PAGE_AXIS));
        sandButton = new JRadioButton("Sandy terrain");
        sandButton.setSelected(true);
        rockButton = new JRadioButton("Rocky terrain");
        waterButton = new JRadioButton("Water");
        grassButton = new JRadioButton("Grassy terrain");
        treeButton = new JRadioButton("Tree on grassy terrain");
        group = new ButtonGroup();
        group.add(sandButton); group.add(rockButton); group.add(waterButton);
        group.add(grassButton); group.add(treeButton);

        JPanel sandPan = new JPanel(new FlowLayout(FlowLayout.LEADING));
        sandPan.add(sandSampler); sandPan.add(sandButton);

        JPanel rockPan = new JPanel(new FlowLayout(FlowLayout.LEADING));
        rockPan.add(rockSampler); rockPan.add(rockButton);

        JPanel waterPan = new JPanel(new FlowLayout(FlowLayout.LEADING));
        waterPan.add(waterSampler); waterPan.add(waterButton);

        JPanel grassPan = new JPanel(new FlowLayout(FlowLayout.LEADING));
        grassPan.add(grassSampler); grassPan.add(grassButton);

        JPanel treePan = new JPanel(new FlowLayout(FlowLayout.LEADING));
        treePan.add(treeSampler); treePan.add(treeButton);
        
        JPanel healthPan = new JPanel(new FlowLayout(FlowLayout.LEADING));
        healthSlider = new JSlider(JSlider.HORIZONTAL,0,health,TileTree.getTreeMax());
        healthLab = new JLabel();
        JLabel healthDecLab = new JLabel();
        healthDecLab.setText("Tree Health: ");
        healthLab.setText(""+healthSlider.getValue());
        healthSlider.setMajorTickSpacing(TileTree.getTreeMax()/5);
        healthSlider.setMinorTickSpacing(TileTree.getTreeMax()/20);
        healthSlider.setPaintTicks(true);
        healthSlider.setPaintLabels(true);
        healthPan.add(largeTreeSampler);
        healthPan.add(healthDecLab);
        healthPan.add(healthLab);
        
        TERchoose.add(sandPan);
        TERchoose.add(rockPan);
        TERchoose.add(waterPan);
        TERchoose.add(grassPan);
        TERchoose.add(treePan);
        //TERchoose.add(healthPan);
        //TERchoose.add(healthSlider);
        TERchoose.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Terrain Types"), BorderFactory.createEmptyBorder(5,5,5,5)), TERchoose.getBorder()));
        
        JPanel setResetPan = new JPanel(new GridLayout(0,1));
        setResetPan.add(randomButton);
        setResetPan.add(clearButton);
        setResetPan.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
        BorderFactory.createTitledBorder("Set or Reset Terrain"), BorderFactory.createEmptyBorder(5,5,5,5)), setResetPan.getBorder()));
        
        JPanel editPan = new JPanel();
        editPan.setLayout(new BoxLayout(editPan,BoxLayout.PAGE_AXIS));
        editPan.add(setResetPan);
        editPan.add(islandsize);
        editPan.add(TERchoose);
        
        JPanel editParPan = new JPanel(new BorderLayout());
        editParPan.add(editPan, BorderLayout.NORTH);
        editParPan.add(new JPanel(), BorderLayout.CENTER);
        

        JScrollPane editPanSC = new JScrollPane(editParPan);
        editPanSC.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        editPanSC.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        


        JPanel currentStatus = new JPanel();
        currentStatus.setLayout(new BoxLayout(currentStatus,BoxLayout.PAGE_AXIS));
        //currentStatus.add(loadStatus);
        //currentStatus.add(editStatus);
        currentStatus.setBorder(BorderFactory.createCompoundBorder( BorderFactory.createCompoundBorder(
                BorderFactory.createTitledBorder("Current HexIsland Status"), BorderFactory.createEmptyBorder(5,5,5,5)), currentStatus.getBorder()));

        //setStatus();
        this.add(editPanSC);

        /**
         * Mouse listeners to update the 
         */
        canvas.addMouseListener(new MouseListener() {
            public void mousePressed(MouseEvent e) {
                applyMouse(e.getX(), e.getY());
            }
            public void mouseReleased(MouseEvent e) {}
            public void mouseEntered(MouseEvent e) {}
            public void mouseExited(MouseEvent e) {}
            public void mouseClicked(MouseEvent e) {}
        });
        canvas.addMouseMotionListener(new MouseMotionListener() {
            public void mouseDragged(MouseEvent e) {
                applyMouse(e.getX(), e.getY()); //If the mouse is clicked, apply the terrain
            }
            public void mouseMoved(MouseEvent e) {}
        });

        /**
         * Change listeners for editing the labels to show the new x and y values
         */
        xSlider.addChangeListener(new ChangeListener(){
            public void stateChanged(ChangeEvent e){
                xLab.setText("X: "+xSlider.getValue());
            }
        });
        ySlider.addChangeListener(new ChangeListener(){
            public void stateChanged(ChangeEvent e){
                yLab.setText("Y: "+ySlider.getValue());
            }
        });
        
        /**
         * Change listener for the changes on the tree heath
         */
        healthSlider.addChangeListener(new ChangeListener(){
            public void stateChanged(ChangeEvent e){
                healthLab.setText(""+healthSlider.getValue());
                largeTreeSampler.setTreeHealth(healthSlider.getValue()); //The tree health for the square
                treeSampler.setTreeHealth(healthSlider.getValue()); //The tree health for the tree
                health = healthSlider.getValue();
                treeButton.setSelected(true); //Select the radio button for trees
            }
        });
        
        applySizeButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                island.setSize(xSlider.getValue(), ySlider.getValue());
                //editedBoo = true;
                //setStatus();
            }
        });

        ChangeListener myRadioListener = new ChangeListener(){
            public void stateChanged(ChangeEvent e) {
                if(sandButton.getModel()==group.getSelection()){selectedTileType=TileType.SAND;}
                else if(rockButton.getModel()==group.getSelection()){selectedTileType=TileType.ROCK;}
                else if(waterButton.getModel()==group.getSelection()){selectedTileType=TileType.WATER;}
                else if(grassButton.getModel()==group.getSelection()){selectedTileType=TileType.GRASS;}
                else if(treeButton.getModel()==group.getSelection()){selectedTileType=TileType.TREE;}
            }
        };
        sandButton.addChangeListener(myRadioListener);
        rockButton.addChangeListener(myRadioListener);
        waterButton.addChangeListener(myRadioListener);
        grassButton.addChangeListener(myRadioListener);
        treeButton.addChangeListener(myRadioListener);

        randomButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                island.randomize();
                //loadedIsland = null;
                //editedBoo = false;
                //setStatus();
            }
        });
        
        clearButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                island.clear();
                //loadedIsland = null;
                //editedBoo = false;
                //setStatus();
            }
        });
        /*        
        chooseDir.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent ae){
                File f = RIO.chooseDirectory();
                if(f != null){loadedDirectory = f;}
                updateFileView();
            } 
        });
        
        saveBut.addActionListener(new ActionListener(){ 
            public void actionPerformed(ActionEvent ae){
                if(RIO.saveTerrain(TER,loadedIsland)){
                    editedBoo = false;
                }
                setStatus();
            }   
        });
        
        saveAsBut.addActionListener(new ActionListener(){ 
            public void actionPerformed(ActionEvent ae){
                File f = RIO.newFileName(loadedDirectory , "ter");
                if(f != null){
                    if(RIO.saveTerrain(TER,f)){
                        editedBoo = false;
                    }
                }
                setStatus();
            }   
        });
        
        loadBut.addActionListener(new ActionListener(){ 
            public void actionPerformed(ActionEvent ae){
                if(choicesArea.getSelectedIndex() >= 0 && choicesArea.getSelectedIndex() < dirContent.length){
                    TER = RIO.loadTerrain(dirContent[choicesArea.getSelectedIndex()]);
                    iFrame.setTER(TER);
                    setDIM();
                    xSlider.setValue(xDIM);
                    ySlider.setValue(yDIM);
                    loadedIsland = TER.getLI();
                    editedBoo = false;
                    setStatus();
                }else{
                    JOptionPane.showMessageDialog(null, "No file has been selected to load.");
                }
            }   
        });
        
        deleteBut.addActionListener(new ActionListener(){ 
            public void actionPerformed(ActionEvent ae){
                if(choicesArea.getSelectedIndex() >= 0 && choicesArea.getSelectedIndex() < dirContent.length){
                    RIO.deleteFile(dirContent[choicesArea.getSelectedIndex()]);
                    setStatus();
                }else{
                    JOptionPane.showMessageDialog(null, "No file has been selected to delete.");
                    setStatus();
                }
            }   
        });*/
    }
    
    private void applyMouse(int xmouse,int ymouse){
    	int q = islandCanvas.getQbyMouse(xmouse, ymouse);
    	int r = islandCanvas.getRbyMouse(xmouse, ymouse);
    	
    	TileType g = getSelectedTileType();
    	island.setTile(q, r, TileFactory.newTile(g));
        islandCanvas.repaint();
    }
    
    private TileType getSelectedTileType() {
		return selectedTileType;
	}

	
    
    /**
     * Updates the list of files to display
     */
    public void updateFileView(){
        //dirLab.setText(io.getCurrentDir().getPath());
        //dirContent = io.getDirContent(extensions);
        /*for(int i = 0;i<names.length;i++){
            names[i] = directory[i].getName(); //populate names
        }
        return names;*/
        //choicesArea.setListData(dirContent);
    }

    
    /**
     * Gives a readout of the status of the current file
     */
    /*private void setStatus(){
        if(loadedIsland == null){
            saveBut.setEnabled(false);
            loadStatus.setText("The current HexIsland is a new, unsaved island.");
            if(!editedBoo){editStatus.setText("\nThe island has not been edited.");
            }else{editStatus.setText("\nThe island has been edited.");}
        }else{
            saveBut.setEnabled(true);
            loadStatus.setText("This is island "+loadedIsland.getName()+".");
            if(!editedBoo){editStatus.setText("\nThe island has not been edited.");
            }else{editStatus.setText("\nThe island has been edited but not saved.");}
        }
        updateFileView();
    } */
}